#include <alt_types.h>
#include <fifo_to_amm_regs.h>
#include "fifo_to_amm.h"

static alt_u32 	base_addr;			//!< Адрес аппаратного модуля.
static alt_u32 	fblock_ofst;		//!< Смещение до 1 блока
static alt_u32 	frame_ofst;			//!< Смещение до пакета в блоке

alt_u8 fifo_to_amm_init(alt_u32 addr)
{
	base_addr = addr;
	return 0;
}


alt_u8 fifo_to_amm_reset()
{
	alt_u8 	err = 0;

	// Команда сброс
	IOWR_FIFO_TO_AMM_CTRL(base_addr,	1 << FIFO_TO_AMM_CTRL_CMD_OFST);
	return err;
}



alt_u8 fifo_to_amm_get_framenum(alt_u16* num)
{
	alt_u8 			err = 0;
	status_reg_t	status;

	// Считываем статус и проверяем, если буфер не пустой, можно считывать размер.
	// При пустом буфере размер останется 0.
	status.data	= IORD_FIFO_TO_AMM_STATUS(base_addr);
	if (!status.empty)
	{
		*num = IORD_FIFO_TO_AMM_FRAMECNT(base_addr) & FIFO_TO_AMM_FRAMECNT_MSK;
	}
	else
	{
		err = 1;
	}

	return err;
}


alt_u8 fifo_to_amm_get_framenum_next(alt_u16* num)
{
	alt_u8 			err = 0;
	status_reg_t	status;

	// Считываем статус и проверяем, если буфер не пустой,
	// можно считывать размер и удалить этот пакет.
	// При пустом буфере размер останется 0.
	status.data	= IORD_FIFO_TO_AMM_STATUS(base_addr);
	if (status.empty)
	{
		*num = IORD_FIFO_TO_AMM_FRAMECNT(base_addr) & FIFO_TO_AMM_FRAMECNT_MSK;

		IOWR_FIFO_TO_AMM_CTRL(base_addr, 2 << FIFO_TO_AMM_CTRL_CMD_OFST);
	}
	else
	{
		err = 1;
	}
	return err;
}

alt_u8 fifo_to_amm_get_addr(alt_u32* addr)
{
	alt_u8 			err = 0;
	status_reg_t	status;

	// Считываем статус и проверяем, если буфер не пустой,
	// можно считывать адрес.
	// При пустом буфере адрес устанавливается 0xFFFFFFFF.
	status.data	= IORD_FIFO_TO_AMM_STATUS(base_addr);
	if (status.empty)
	{
		*addr = ((IORD_FIFO_TO_AMM_BLOCKCNT(base_addr) & FIFO_TO_AMM_BLOCKCNT_MSK) << FIFO_TO_AMM_BLOCKSIZE_LOG2) + fblock_ofst;
	}
	else
	{
		err = 1;
	}

	return err;
}

alt_u8 fifo_to_amm_get_addr_next(alt_u32* addr)
{
	alt_u8 			err = 0;
	status_reg_t	status;

	// Считываем статус и проверяем, если буфер не пустой,
	// можно считывать адрес и удалять пакет.
	// При пустом буфере адрес устанавливается 0xFFFFFFFF.
	status.data	= IORD_FIFO_TO_AMM_STATUS(base_addr);
	if (!status.empty)
	{
		*addr = (((IORD_FIFO_TO_AMM_BLOCKCNT(base_addr) & FIFO_TO_AMM_BLOCKCNT_MSK)) << FIFO_TO_AMM_BLOCKSIZE_LOG2) + fblock_ofst;

		IOWR_FIFO_TO_AMM_CTRL(base_addr, 2 << FIFO_TO_AMM_CTRL_CMD_OFST);
	}
	else
	{
		err = 1;
	}

	return err;
}

alt_u8 fifo_to_amm_set_fblock_ofst(alt_u32 ofst)
{
	alt_u8 	err = 0;

	fblock_ofst	= ofst;
	IOWR_FIFO_TO_AMM_FBLOCKOFST(base_addr, ofst);
	return err;
}

alt_u8 fifo_to_amm_set_frame_ofst(alt_u32 ofst)
{
	alt_u8 	err = 0;

	frame_ofst = ofst;
	IOWR_FIFO_TO_AMM_FRAMEOFST(base_addr, ofst);
	return err;
}
